import sys, os
sys.path.append(os.path.dirname(__file__)) 
os.chdir(os.path.dirname(__file__))

#redirect without entry script
os.environ["SCRIPT_NAME"] = '' 
os.environ["REAL_SCRIPT_NAME"] = ''

import web 
import time
import routes
import tempfile
import json
import webhdfs
import urllib
import mimetypes
import uuid
import zipfile
import shutil
from config import setting
from datetime import *

web.config.debug = True

webhdfsItem =webhdfs.WebHDFS('localhost', '50070', 'hadoopuser')
db = web.database(dbn='mysql', host='localhost',db='ladybug',user='root',pw='it901694')


app = web.application(routes.urls, globals())
web.config.session_parameters['cookie_name'] = 'session_id'
#use session in debug mode
if web.config.get('_session') is None:
	session = web.session.Session(app,web.session.DiskStore(os.path.dirname(__file__)+'/sessions'),initializer = {'count':0,'login':0,'privilege':0,'userId':'','userName':'','userEmail':''})
	web.config._session = session
else:
	session = web.config._session
render = web.template.render(os.path.dirname(__file__)+'/templates',cache = False,base = 'layout',globals = {'context':session})
class Index:
	def GET(self):
		web.seeother('/home')
class Home:
	def GET(self):
	 	name = 'wentworth zheng'
		return render.index(name)		

class Login:
	def GET(self):
		if logged():
			raise web.seeother('/home')
		else:
			login = web.template.frender('templates/login.html')
			return login()
	def POST(self):
		email,passwd = web.input().email,web.input().passwd
		ident = db.query("select * from user where email = '%s'" % (email))[0]
		try:
			if passwd == ident.password:
				session.login = 1
				session.privilege = ident.privilege
				session.userName = ident.name
				session.userId = ident.id
				session.userEmail = ident.email
				web.seeother('/home')
			else:
				session.login = 0
				session.privilege = 0
				return "Again"
		except:
			session.login = 0
			session.privilege = 0
			return ident.password,passwd

class Delete:
	def POST(self):
		return webhdfsItem.rmdir(urllib.quote(web.input().path))

class Create:
	def POST(self):
		if webhdfsItem.mkdir(urllib.quote(web.input().path)):
			record = webhdfsItem.getFileStatus(urllib.quote(web.input().path))
			record.setdefault('path',web.input().path+record['pathSuffix'])
			record['filename'] = web.input().filename
			record = fileStatusHandler(record)
			return json.dumps(record)
		else:
			return json.dumps({'status':'failure'})

class Update:
	def POST(self):
		if webhdfsItem.rename(urllib.quote(web.input().origin),urllib.quote(web.input().target)):
			return json.dumps({'status':'success'})
		else:
			return json.dumps({'status':'failure'})
		
		return None

class ListDirectory:
	def GET(self):
		web.header('Content-Type','application/json')
		path = web.input().path
		result = webhdfsItem.getContent(urllib.quote(path))
		path = pathHandler(path)
		for index,record in enumerate(result):
			record.setdefault('path',path+record['pathSuffix'])
			record = fileStatusHandler(record)
		return json.dumps(result)

class UploadFile:
	def GET(self):
		return (web.input())
	def POST(self):
		file = web.webapi.rawinput().file
		target = pathHandler(web.webapi.rawinput().path) + file.filename
		webhdfsItem.copyFromLocal(file.file,urllib.quote(target))
		record = webhdfsItem.getFileStatus(urllib.quote(target))
		record.setdefault('path',target)
		record['filename'] = file.filename
		record = fileStatusHandler(record)
		return json.dumps(record)

class Download:
	def POST(self):
		id = str(uuid.uuid1())
		container = 'download/'+id
		archive = 'download/'+id+'.zip'
		target =  web.input()
		if target.type == 'mixed':
			os.makedirs(container)
			files = json.loads(web.webapi.rawinput().files)
			lst = []
			for file in files:
				if file['type'] != 'folder':
					webhdfsItem.copyToLocal(urllib.quote(file['path']),container+'/'+file['filename'])
				else:
					getFolder(file['path'],'/',container)
			zip_dir(container,archive)
			return  json.dumps({'status':'success','export_url':'/archive/'+urllib.quote(id)+'.zip'})
		else:
			if target.type != 'folder':
				webhdfsItem.copyToLocal(urllib.quote(target.path),'download/'+urllib.quote(id))
				return json.dumps({'status':'success','export_url':'/export/'+urllib.quote(id+'/'+target.filename)})
			else:			
				getFolder(web.input().path,'/',container)
				zip_dir(container,archive)
				# shutil.rmtree(container)				
				return json.dumps({'status':'success','export_url':'/archive/'+urllib.quote(id)+'.zip'})

class LD:
	def GET(self):
		web.header('Content-Type','application/json')
		path = web.input().path
		result = webhdfsItem.getContent(urllib.quote(path))
		path = pathHandler(path)
		lst = []
		for index,record in enumerate(result):
			if record['type'] != 'DIRECTORY':	continue
			lst.append({'id':'0','name':record['pathSuffix'],'isParent': True})
		return json.dumps(lst)

class Move:
	def POST(self):			
		if webhdfsItem.rename(urllib.quote(web.input().source),urllib.quote(web.input().target)):
			return json.dumps({'status':'success'})
		else:
			return json.dumps({'status':'failure'})

class Archive:
	def GET(self,target):
		archive = open('download/'+target)
		web.header('Content-Type','application/octet-stream')
		web.header('Content-disposition','attachment:filename=%s' % 'Ladybug.zip')
		while True:
			c = archive.read()
			if c:
				yield c
			else:
				break

class Export:
	def GET(self,target,name):
		try:
			archive = open('download/'+target)
			web.header('Content-Type','application/octet-stream')
			if name == None:				
				web.header('Content-disposition','attachment:filename=Ladybug.zip')
			else:
				web.header('Content-disposition','attachment:filename=%s' % name)
			while True:
				c = archive.read()
				if c:
					yield c
				else:
					break
		except Exception,e:
			pass

class Test:
	def GET(self):
		shutil.rmtree('download/8e08c1dc-a636-11e2-acb3-1c4bd659e51e')
		return session
class Logout:
	def GET(self):
		session.login = 0
		session.kill()
		web.seeother('/login')

def pathHandler(path):
	if path[-1:] != '/':
			path +='/'
	return path
def fileStatusHandler(record):
	record.setdefault('filename',record['pathSuffix'])	
	record.setdefault('modTime',datetime.fromtimestamp(record['modificationTime']/1000).strftime('%Y-%m-%d %H:%M:%S'))
	record['accessTime']=datetime.fromtimestamp(record['accessTime']/1000).strftime('%Y-%m-%d %H:%M:%S')
	if record['type'] == 'FILE':
		record['type'] = mimetypes.guess_type(record['filename'])[0]
		if record['type'] == None:
			record['type'] = 'unknowing'
	elif record['type'] == 'DIRECTORY':
		record['type'] = 'folder'
	del record['pathSuffix']
	del record['modificationTime']
	return record

def logged():
    if session.login==1:
        return True
    else:
        return False

def getFolder(root,relative,container):
	name = root + relative
	currentFolder =container+'/'+root.split('/').pop()+relative
	if not os.path.exists(currentFolder):
		os.makedirs(currentFolder)
	result = webhdfsItem.getContent(urllib.quote(name))
	for record in result:
		if record['type'] =='DIRECTORY':
			getFolder(root,pathHandler(relative)+record['pathSuffix'],container)
		else:
			webhdfsItem.copyToLocal(name,currentFolder+'/'+record['pathSuffix'])

def zip_dir(dirname,zipfilename):
    filelist = []
    if os.path.isfile(dirname):
        filelist.append(dirname)
    else :
        for root, dirs, files in os.walk(dirname):
            for name in files:
                filelist.append(os.path.join(root, name))
        
    zf = zipfile.ZipFile(zipfilename, "w", zipfile.zlib.DEFLATED)
    for tar in filelist:
        arcname = tar[len(dirname):]
        #print arcname
        zf.write(tar,arcname)
    zf.close()

def unzip_file(zipfilename, unziptodir):
    if not os.path.exists(unziptodir): os.mkdir(unziptodir, 0777)
    zfobj = zipfile.ZipFile(zipfilename)
    for name in zfobj.namelist():
        name = name.replace('\\','/')
       
        if name.endswith('/'):
            os.mkdir(os.path.join(unziptodir, name))
        else:            
            ext_filename = os.path.join(unziptodir, name)
            ext_dir= os.path.dirname(ext_filename)
            if not os.path.exists(ext_dir) : os.mkdir(ext_dir,0777)
            outfile = open(ext_filename, 'wb')
            outfile.write(zfobj.read(name))
            outfile.close()
def auth():
	if web.ctx.path not in ['/login','/logout']:
		if not (session.login == 1):
			raise web.seeother('/login')

app.add_processor(web.loadhook(auth))
app.notfound = lambda : web.notfound('Sorry ,the page your were looking for was not found.')
application = app.wsgifunc()